﻿using System;
using System.ComponentModel;
using System.Globalization;
using System.Linq.Expressions;
using System.Threading;
using System.Windows;

namespace Tequila.Phone.Infrastructure.Localization
{
    /// <summary>
    /// Base implementation of <see cref="ILocalizationManager"/>.
    /// </summary>
    public abstract class LocalizationManagerBase : ILocalizationManager, INotifyPropertyChanged
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cultureInfo"></param>
        public static void ResetThreadCultures(CultureInfo cultureInfo)
        {
            Thread.CurrentThread.CurrentCulture = cultureInfo;
            Thread.CurrentThread.CurrentUICulture = cultureInfo;
        }

        /// <summary>
        /// Gets <see cref="Application.Current">Current Application</see> related <see cref="LocalizationManagerBase">Localization Manager</see>.
        /// </summary>
        public static LocalizationManagerBase Current
        {
            get { return Application.Current.GetCurrentLocalizationManager<LocalizationManagerBase>(); }
        }

        /// <summary>
        /// Performs custom resources reset operation.
        /// </summary>
        protected virtual void ResetResources()
        {

        }

        /// <summary>
        /// Triggers PropertyChanged <see cref="PropertyChangedEventHandler">event</see>.
        /// </summary>
        /// <param name="propertyName">Property name.</param>
        protected void OnPropertyChanged(string propertyName)
        {
            if(string.IsNullOrEmpty(propertyName))
            {
                throw new ArgumentException(string.Empty, "propertyName");
            }

            var handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Triggers PropertyChanged <see cref="PropertyChangedEventHandler">event</see>.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression"><see cref="Expression{TDelegate}">Expression</see> determining property name.</param>
        protected void OnPropertyChanged<T>(Expression<Func<T>> expression)
        {
            var handler = PropertyChanged;

            if(handler != null)
            {
                handler(this, new PropertyChangedEventArgs(expression.GetMemberName()));
            }
        }

        #region Implementation of INotifyPropertyChanged

        /// <summary>
        /// Property Changed Event.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Implementation of ILocalizationManager

        /// <summary>
        /// Resets <see cref="CultureInfo">culture</see> for all related resources.
        /// </summary>
        /// <param name="cultureInfo"><see cref="CultureInfo">Culture</see>.</param>
        public void ResetCulture(CultureInfo cultureInfo)
        {
            ResetThreadCultures(cultureInfo);

            ResetResources();
        }

        #endregion
    }
}
